#include "StdAfx.h"
#include "MyProtocol.h"
#include "TypeIds.h"
#include "MyPayload.h"

namespace CO { namespace MyGroupNamespace { namespace MyPackageNamespace {

MyProtocol::MyProtocol(bool conjugate, bool isLogged) :
	ContractChecker(conjugate, isLogged)	// Initialize base class.
{
}

MyProtocol::~MyProtocol(void)
{
}

bool MyProtocol::validMessage(SpiFoundation::RoomFW::MessageID messageID, const SpiFoundation::RoomFW::IPayloadSP& payload) const
{
	bool retVal = false;

	//
	// In Messages:
	//
	if (!this->isConjugate())
	{
		//
		// TODO:  Check each valid in message id for correct payload type (or null).
		//
		switch (messageID)
		{
		case IN_MESSAGE_1:
			ASSERT(SpiFoundation::RoomFW::IPayload::IsSafe(PTID_MY_PAYLOAD_ID, payload));
			retVal = SpiFoundation::RoomFW::IPayload::IsSafe(PTID_MY_PAYLOAD_ID, payload);
			break;
		case IN_MESSAGE_2:
			ASSERT(0 == payload);
			retVal = (0 == payload);
			break;
		case IN_MESSAGE_3:
			ASSERT(0 == payload);
			retVal = (0 == payload);
			break;
		case IN_ERROR_1:
			ASSERT(0 == payload);
			retVal = (0 == payload);
			break;
		case IN_ERROR_2:
			ASSERT(0 == payload);
			retVal = (0 == payload);
			break;
		case IN_ERROR_3:
			ASSERT(0 == payload);
			retVal = (0 == payload);
			break;
		case IN_ERROR_4:
			ASSERT(0 == payload);
			retVal = (0 == payload);
			break;
		case IN_ERROR_5:
			ASSERT(0 == payload);
			retVal = (0 == payload);
			break;
		case I_AM_READY_ACK:
			ASSERT(0 == payload);
			retVal = (0 == payload);
			break;
		default:
			ASSERT(false); // Invalid message id.
		}
	}
	//
	// Out Messages:
	//
	else
	{
		//
		// TODO:  Check each valid out message id for correct payload type (or null).
		//
		switch (messageID)
		{
		case OUT_MESSAGE_1:
			ASSERT(SpiFoundation::RoomFW::IPayload::IsSafe(PTID_MY_PAYLOAD_ID, payload));
			retVal = SpiFoundation::RoomFW::IPayload::IsSafe(PTID_MY_PAYLOAD_ID, payload);
			break;
		case OUT_MESSAGE_2:
			ASSERT(0 == payload);
			retVal = (0 == payload);
			break;
		case OUT_MESSAGE_3:
			ASSERT(0 == payload);
			retVal = (0 == payload);
			break;
		case I_AM_READY:
			ASSERT(0 == payload);
			retVal = (0 == payload);
			break;
		case HARDWARE_DISABLED_EVENT:
			ASSERT(0 == payload);
			retVal = (0 == payload);
			break;
		case SW_ERROR_EVENT:
			ASSERT(0 == payload);
			retVal = (0 == payload);
			break;
		case HW_ERROR_EVENT:
			ASSERT(0 == payload);
			retVal = (0 == payload);
			break;
		case OUT_ERROR:
			ASSERT(SpiFoundation::RoomFW::IPayload::IsSafe(SpiControl::Protocol::PTID_ERROR, payload));
			retVal = SpiFoundation::RoomFW::IPayload::IsSafe(SpiControl::Protocol::PTID_ERROR, payload);
			break;
		default:
			ASSERT(false); // Invalid message id.
		}
	}
	return retVal;
}

const char* MyProtocol::messageName(SpiFoundation::RoomFW::MessageID messageID) const
{
	const char* retVal = "***UNKNOWN***";
	//
	// TODO:  Add text for each message id for debugging.
	//
	switch (messageID)
	{
	case IN_MESSAGE_1:
		retVal = "IN_MESSAGE_1";
		break;
	case IN_MESSAGE_2:
		retVal = "IN_MESSAGE_2";
		break;
	case IN_MESSAGE_3:
		retVal = "IN_MESSAGE_3";
		break;
	case IN_ERROR_1:
		retVal = "IN_ERROR_1";
		break;
	case IN_ERROR_2:
		retVal = "IN_ERROR_2";
		break;
	case IN_ERROR_3:
		retVal = "IN_ERROR_3";
		break;
	case IN_ERROR_4:
		retVal = "IN_ERROR_4";
		break;
	case IN_ERROR_5:
		retVal = "IN_ERROR_4";
		break;
	case I_AM_READY_ACK:
		retVal = "I_AM_READY_ACK";
		break;
	case OUT_MESSAGE_1:
		retVal = "OUT_MESSAGE_1";
		break;
	case OUT_MESSAGE_2:
		retVal = "OUT_MESSAGE_2";
		break;
	case OUT_MESSAGE_3:
		retVal = "OUT_MESSAGE_3";
		break;
	case I_AM_READY:
		retVal = "I_AM_READY";
		break;
	case HARDWARE_DISABLED_EVENT:
		retVal = "HARDWARE_DISABLED_EVENT";
		break;
	case SW_ERROR_EVENT:
		retVal = "SW_ERROR_EVENT";
		break;
	case HW_ERROR_EVENT:
		retVal = "HW_ERROR_EVENT";
		break;
	case OUT_ERROR:
		retVal = "OUT_ERROR";
		break;
	default:
		ASSERT(false); // Invalid message id.
	}
	return retVal;
}

SpiFoundation::RoomFW::ContractTypeId MyProtocol::getTypeID() const
{
	//
	// TODO:  Return a unique id for your protocol.
	//
	return CTID_MY_PROTOCOL_ID;
}

SpiFoundation::RoomFW::IContractCheckerSPC MyProtocol::getConjugate(void) const
{
	//
	// TODO:  Create a new instance of this class with opposite conjugation.
	//
	return SpiFoundation::RoomFW::IContractCheckerSPC(new MyProtocol(!this->isConjugate()));
}

SpiFoundation::RoomFW::IPayloadSP MyProtocol::createPayload(SpiFoundation::RoomFW::MessageID messageID) const
{
	//
	// TODO:  Create a default payload object for each message id.
	//
	// Note:  This is only used for binding over TCP/IP.
	//
	//switch (messageID)
	//{
	//case IN_MESSAGE_1:
	//	return MyPayloadSP(new MyPayload(0.0));
	//case OUT_MESSAGE_1:
	//	return MyPayloadSP(new MyPayload(0.0));
	//default:
	//	ASSERT(false); // Invalid message id.
	//}
	return SpiFoundation::RoomFW::IPayloadSP(); // To quite the compiler.
}

}}} // End namespace
